/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tdtest.controls;


import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.text.Text;
import res.ImageLoader;
import tdtest.action.NameEditAction;
import tdtest.action.NotesEditAction;
import tdtest.action.WindowAction;
import tdtest.data.TDSystemComponent;

/**
 *
 * @author sutter
 */
public abstract class SystemComponentControl<T extends TDSystemComponent> extends GridPane implements DataControl<T> {
	
	private final static int SHOW_NOTES = 1;
	private final static int SHOW_CONTENT = 2;
	
	public enum WindowState {
		MIN(0),
		NOTES(SHOW_NOTES),
		CONTENT(SHOW_CONTENT),
		ALL(SHOW_NOTES | SHOW_CONTENT);
		
		//data
		int flags;
		WindowState(int flags) {
			this.flags = flags;
		}
		public int getFlags() {
			return flags;
		}
	}
	
	private T data;
	private Label nameLabel;
	private Button nameEditButton;
	private HBox namePrefixPane;
	private HBox nameSuffixPane;
	private HBox windowControlPane;
	private ToggleButton minWindowButton;
	private ToggleButton notesWindowButton;
	private ToggleButton contentWindowButton;
	private ToggleButton allWindowButton;
	private ToggleGroup windowGroup;
	private Text notesText;
	private Button notesEditButton;
	private Node content;
	private WindowState windowState = WindowState.MIN;
	
	public SystemComponentControl(T data) {
		this.data = data;
		init();
		getStyleClass().add("system-component-control");
		data.addOnChanagedListener(this);
	}
	
	@Override
	public T getData() {
		return data;
	}
	
	// on changed listener interface
	@Override
	public void onUpdate() {
			
		String name = data.name;
		String notes = data.notes;
		if(name == null) {name = "";}
		if(notes == null) {notes = "";}

		nameLabel.setText(name);
		notesText.setText(notes);
	}
	
	@Override
	public void onDelete() {
		//no action
	}
	
	private void init() {		
		ColumnConstraints column0 = new ColumnConstraints();
		this.getColumnConstraints().addAll(column0);
		ColumnConstraints column1 = new ColumnConstraints();
		this.getColumnConstraints().addAll(column1);
		ColumnConstraints column2 = new ColumnConstraints();
		this.getColumnConstraints().addAll(column2);
		ColumnConstraints column3 = new ColumnConstraints();
		this.getColumnConstraints().addAll(column3);
		ColumnConstraints column4 = new ColumnConstraints(10,10,Double.MAX_VALUE);
		column4.setHgrow(Priority.ALWAYS);
		this.getColumnConstraints().addAll(column4);
		
		nameEditButton = new Button();
		nameEditButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent e) {
				NameEditAction action = new NameEditAction(data);
				action.run();
			}
		});
		Image editImage = ImageLoader.getImage("edit.png");
		nameEditButton.setGraphic(new ImageView(editImage));
		nameEditButton.getStyleClass().add("edit-button");
		nameEditButton.getStyleClass().add("image-button");
		
		namePrefixPane = new HBox();
		namePrefixPane.getStyleClass().add("name-prefix-pane");
				
		nameLabel = new Label();
		nameLabel.getStyleClass().add("name-text");
		
		nameSuffixPane = new HBox();
		nameSuffixPane.getStyleClass().add("name-suffix-pane");
		
		windowControlPane = new HBox();
		windowControlPane.getStyleClass().add("window-control-pane");	
		
		windowGroup = new ToggleGroup();
		
		minWindowButton = new ToggleButton();
		
		Image image;
		
		minWindowButton = new ToggleButton();
		if(windowState == WindowState.MIN) minWindowButton.setSelected(true);
		minWindowButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent e) {
				//do button action based on select
				if(!minWindowButton.isSelected()) {
					//default behavior is to deselect - reselect and exit
					minWindowButton.setSelected(true);
					return;
				}
				else {
					WindowAction action = new WindowAction(SystemComponentControl.this,WindowState.MIN);
					action.run();
				}
			}
		});
		minWindowButton.getStyleClass().add("min-window-button");
		minWindowButton.getStyleClass().add("image-toggle-button");
		image = ImageLoader.getImage("window-min.png");
		minWindowButton.setGraphic(new ImageView(image));
		minWindowButton.setToggleGroup(windowGroup);
		windowControlPane.getChildren().add(minWindowButton);
		
		notesWindowButton = new ToggleButton();
		if(windowState == WindowState.NOTES) notesWindowButton.setSelected(true);
		notesWindowButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent e) {
				//do button action based on select
				if(!notesWindowButton.isSelected()) {
					//default behavior is to deselect - reselect and exit
					notesWindowButton.setSelected(true);
					return;
				}
				else {
					WindowAction action = new WindowAction(SystemComponentControl.this,WindowState.NOTES);
					action.run();
				}
			}
		});
		image = ImageLoader.getImage("window-notes.png");
		notesWindowButton.setGraphic(new ImageView(image));
		notesWindowButton.getStyleClass().add("notes-window-button");
		notesWindowButton.getStyleClass().add("image-toggle-button");
		notesWindowButton.setToggleGroup(windowGroup);
		windowControlPane.getChildren().add(notesWindowButton);
		
		contentWindowButton = new ToggleButton();
		if(windowState == WindowState.CONTENT) contentWindowButton.setSelected(true);
		contentWindowButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent e) {
				//do button action based on select
				if(!contentWindowButton.isSelected()) {
					//default behavior is to deselect - reselect and exit
					contentWindowButton.setSelected(true);
					return;
				}
				else {
					WindowAction action = new WindowAction(SystemComponentControl.this,WindowState.CONTENT);
					action.run();
				}
			}
		});
		image = ImageLoader.getImage("window-content.png");
		contentWindowButton.setGraphic(new ImageView(image));
		contentWindowButton.getStyleClass().add("content-window-button");
		contentWindowButton.getStyleClass().add("image-toggle-button");
		contentWindowButton.setToggleGroup(windowGroup);
		windowControlPane.getChildren().add(contentWindowButton);
		
		allWindowButton = new ToggleButton();
		if(windowState == WindowState.ALL) allWindowButton.setSelected(true);
		allWindowButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent e) {
				//do button action based on select
				if(!allWindowButton.isSelected()) {
					//default behavior is to deselect - reselect and exit
					allWindowButton.setSelected(true);
					return;
				}
				else {
					WindowAction action = new WindowAction(SystemComponentControl.this,WindowState.ALL);
					action.run();
				}
			}
		});
		image = ImageLoader.getImage("window-all.png");
		allWindowButton.setGraphic(new ImageView(image));
		allWindowButton.getStyleClass().add("all-window-button");
		allWindowButton.getStyleClass().add("image-toggle-button");
		allWindowButton.setToggleGroup(windowGroup);
		windowControlPane.getChildren().add(allWindowButton);
		
		notesEditButton = new Button();
		notesEditButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override public void handle(ActionEvent e) {
				NotesEditAction action = new NotesEditAction(data);
				action.run();
			}
		});
		notesEditButton.setGraphic(new ImageView(editImage));
		notesEditButton.getStyleClass().add("edit-button");
		notesEditButton.getStyleClass().add("image-button");
		
		notesText = new Text();
		notesText.setWrappingWidth(600);
		notesText.getStyleClass().add("notes-text");
		
		//set the data fields
		if(data.name != null) {
			nameLabel.setText(data.name);
		}
		if(data.notes != null) {
			notesText.setText(data.notes);
		}
		
		//update the layout, according to the window state
		setWindowState(windowState);
	};
	
	public HBox getNamePrefixPane() {
		return namePrefixPane;
	}
	
	public HBox getNameSuffixPane() {
		return nameSuffixPane;
	}
	
	protected final void setContent(Node node) {
		if(content != null) {
			this.getChildren().remove(content);
		}
		content = node;
		
		//update the layout, according to the window state
		setWindowState(windowState);
	}
	
	/** This method can be used if there is no data component. */
	public void setNullObjectTitle(String name) {
		nameLabel.setText(name);
	}
	
	public void addNameClass(String titleClass) {
		nameLabel.getStyleClass().add(titleClass);
	}
	
	public void addNotesClass(String notesClass) {
		notesText.getStyleClass().add(notesClass);
	}
	
	public void setWindowState(WindowState windowState) {
		this.windowState = windowState;
		
		this.getChildren().clear();
		
		add(nameEditButton, 0, 0);
		add(namePrefixPane, 1, 0);
		add(nameLabel, 2, 0);
		add(nameSuffixPane, 3, 0);
		add(windowControlPane, 4, 0);
		
		if((windowState.getFlags() & SHOW_NOTES) != 0) {
			add(notesEditButton, 0, 1);
			add(notesText, 1, 1, 4, 1);
		}
		if((content != null)&&(windowState.getFlags() & SHOW_CONTENT) != 0) {
			add(content, 0, 2, 5, 1);
		}
	}
}